//
// Created by 李云飞 on 2023/10/29.
//

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include "learn.h"
#include <netinet/in.h>
#include <stdint.h>
#include <thread>
#include <chrono>
#include <typeinfo>
#include <cxxabi.h>
#include <deque>
#include <istream>

using namespace learn;
using namespace std;

#define debug10



int main(){
#ifdef debug10 // 电影院作为排序 中间最小 一边奇数一边偶数 输入流中的非整数数据（如字符或 EOF）将导致 istream_iterator 到达流的末尾，从而结束循环

    istream_iterator<int> it1(std::cin), it2;
    vector<int> srcVec(it1, it2);
    sort(srcVec.begin(), srcVec.end());
    deque<int> outDeque;
    for (auto it = srcVec.begin(); it != srcVec.end(); ++it) {
        if (*it % 2 == 0) {
            outDeque.push_back(*it);
        }
        else {
            outDeque.push_front(*it);
        }
    }
    copy(outDeque.begin(), outDeque.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
#endif

#ifdef debug9 // transform 从输入输入数据 并将其求平均值
    transform(istream_iterator<double>(cin), istream_iterator<double>(), ostream_iterator<double>(cout, " "),
            [](double x) -> double { return x*x; });

#endif

#ifdef debug8 // transform 算法 取反
    vector<int> inVec(4);
    for(auto& it : inVec) {
        cin >> it;
    }
    transform(inVec.begin(), inVec.end(), ostream_iterator<int>(cout, " "), negate<int>());
    cout << endl;
#endif

#ifdef debug7 //将低级符号名解码成用户级名字

    cout << typeid(debug7_Foo*[10]).name() << endl; // 10_PZ4mainE10debug7_Foo

    char* name = abi::__cxa_demangle(typeid(debug7_Foo*[10]).name(), nullptr, nullptr, nullptr);
    cout << name << endl; // learn::debug7_Foo* [10]
    free(name); // 因为__cxa_demangle第二个参数为nullptr时，函数将动态分配内存

#endif

#ifdef debug6 // 查找元素大于10的元素 或查找元素小于10的元素

    std::vector<int> tmp = {12, 3, 34, 33, 3, 5, 12, 6, 7, 9, 10};
    using std::placeholders::_1;
    // 查找元素值大于10的元素个数
    int gCount = std::count_if(tmp.begin(), tmp.end(), std::bind(std::less<int>(), 10, _1));
    std::cout << "gCount: " << gCount <<std::endl;
    // 查找元素值小于10的元素个数
    int lCount = std::count_if(tmp.begin(), tmp.end(), std::bind(std::less<int>(), _1, 10));
    std::cout << "lCount: " << lCount <<std::endl;
    //
    auto f = std::bind(std::logical_and<bool>(),
            std::bind(std::greater<int>(), _1, 5), std::bind(std::less_equal<int>(), _1, 10));
    int glCount = std::count_if(tmp.begin(), tmp.end(), f);
    std::cout << "glCount: " << glCount << std::endl;

#endif



#ifdef debug5
    learn::Print("cpp learn here!");

    std::this_thread::sleep_for(std::chrono::seconds(20));
    uint16_t s;

    //引用折叠
    int x = 10;
    int& var1 = x;
    auto&& var2 = var1;
    std::cout << std::addressof(x) << std::endl;
    std::cout << std::addressof(var1) << std::endl;
    std::cout << std::addressof(var2) << std::endl;
    int&& var3 = 20;
    auto&& var4 = var3;
    std::cout << std::addressof(var3) << std::endl;
#endif


#ifdef debug4
    A&& a = GetA();
    a.a += 1;
    std::cout << a.a << std::endl;
#endif

#ifdef debug3
    // C++17 可以在if或for中定义临时变量
    std::vector<int> vec = {1,2,3,4};
    if ( const std::vector<int>::iterator itr = std::find(vec.begin(),vec.end(),3); itr != vec.end()) {
        *itr = 4;
    }
#endif

#ifdef debug2
    std::cout <<"NULL 与 0 比较 结果：" <<std::is_same<decltype(NULL), decltype(0)>::value << std::endl;
#endif

#ifdef debug1
    //绑定print函数
    int (*BindPrint)(std::string) = Print;
    BindPrint("bind print func");
    //绑定到仿函数
    int (ImitateFunc:: * BindImitateFunc)(int, int) = &ImitateFunc::operator();
    (ImitateFunc().*BindImitateFunc)(8, 4);
    /********************使用std::function*******************************/
    //包装-普通函数
    std::function<int(std::string)> BindPrint2(Print);
    BindPrint2("包装-普通函数");
    //包装-模版函数
    tempFunc<int>(8,5);
    std::function<int(int, int)> BindTempFunc = tempFunc<int>;
    BindTempFunc(8, 3);
    //包装-lambda表达式
    auto LamFunc = [](int i, int j){
        std::cout << "包装-lambda表达式:" << i - j << std::endl;
        return  i - j;
    };
    std::function<int (int, int)> BindLamFunc = LamFunc;
    BindLamFunc(13,3);
    //包装-函数对象-非模版类型
    std::function<int(int, int)> OpeFunc = ImitateFunc();
    OpeFunc(8,2);
    //包装-函数对象-模版类型
    std::function<int(int, int)> TempMinusFunc = Minus();
    TempMinusFunc(9,1);
#endif



    return 0;
}